﻿using CarPCBATest.Procedure;
using Common;
using MahApps.Metro.Controls;
using MahApps.Metro.Controls.Dialogs;
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Markup.Localizer;
using VM.Core;
using VM.PlatformSDKCS;

namespace CarPCBATest.ViewModel
{
    public partial class HomeViewModel : NotifyBase
    {
        public Action SNInputFocusAction;

        bool vmPorjLoaded = false;
        public TestResultData TestResultData { get; set; }

        private void ShowMessage(string msg, string msgType = "错误")
        {
            Application.Current.Dispatcher.Invoke(() =>
            {
                var mwin = Application.Current.MainWindow as MetroWindow;

                mwin.ShowMessageAsync(msgType, msg);
            });
        }

        private bool? _testResult;

        public bool? TestResult
        {
            get { return _testResult; }
            set
            {
                _testResult = value;
                this.DoNotify();
            }
        }

        public HomeViewModel()
        {
            SaveImageCommand = new CommandBase(SaveImage);
            StartCommand = new CommandBase(Start);
            ResetCommand = new CommandBase(Reset);
            LoadedCommand = new CommandBase(Loaded);
            UnloadedCommand = new CommandBase(Unloaded);
            TestResult = null;
            VmSolution.OnWorkStatusEvent += VmSolution_OnWorkStatusEvent;//工作执行状态回调
            VmSolution.OnSolutionLoadEndEvent += VmSolution_OnSolutionLoadEndEvent;
            VmSolution.OnSolutionLoadBeginEvent += VmSolution_OnSolutionLoadBeginEvent;

            MachineStatus = MachineStatus.Stop;
            IOModule.StartAction += StartAction;
            IOModule.EmgStopAction += EmgStopAction;
            IOModule.EmgCancelAction += EmgCancelAction;
        }

        private void VmSolution_OnSolutionLoadBeginEvent(ImvsSdkDefine.IMVS_SOLUTION_LOAD_BEGEIN_INFO solutionLoadBeginInfo)
        {
            vmPorjLoaded = false;
        }

        private void VmSolution_OnSolutionLoadEndEvent(ImvsSdkDefine.IMVS_SOLUTION_LOAD_END_INFO solutionLoadEndInfo)
        {
            try
            {
                VmSolution.Instance.SilentExecute();
            }
            catch (VmException vex)
            {
                Mylog.Error(vex, vex.Message);
                Log = vex.Message;
            }
            vmPorjLoaded = true;
        }

        private void SaveImage(object obj)
        {
            try
            {
                currentProcId = 10003;
                Stopwatch sw = Stopwatch.StartNew();
                for (int i = 0; i < 30; i++)
                {
                    Log = $"save[{i}]";
                    vmProcHaveExec = false;
                    VisionTool.RunProc("SaveImage");
                    while (!vmProcHaveExec) ;
                    Console.WriteLine("视觉执行耗时：" + sw.ElapsedMilliseconds);
                }
            }
            catch (Exception ex)
            {
                Log = ex.Message;
            }
        }

        private void EmgCancelAction()
        {
            switch (MachineStatus)
            {
                case MachineStatus.Running:
                    break;

                case MachineStatus.Stop:
                    break;

                case MachineStatus.EmgStop:
                    MachineStatus = MachineStatus.Stop;
                    break;

                default:
                    break;
            }
        }

        private void EmgStopAction()
        {
            switch (MachineStatus)
            {
                case MachineStatus.Running:
                    MachineStatus = MachineStatus.EmgStop;
                    break;

                case MachineStatus.Stop:
                    MachineStatus = MachineStatus.EmgStop;
                    break;

                case MachineStatus.EmgStop:
                    break;

                default:
                    break;
            }
        }

        private void StartAction()
        {
            Application.Current.Dispatcher.Invoke(() =>
            {
                Start(null);
            });
        }

        private PcbConfig _pcbConfig;

        public PcbConfig PcbConfig
        {
            get { return _pcbConfig; }
            set
            {
                if (value != null)
                {
                    VisionProjPath = value.VisionProjPath;
                }
                _pcbConfig = value;
                this.DoNotify();
            }
        }

        private string _visionProjPath;

        public string VisionProjPath
        {
            get { return _visionProjPath; }
            set
            {
                if (value != _visionProjPath)
                {
                    Log = $"加载视觉方案";
                    if (File.Exists(value))
                    {
                        Task.Run(() =>
                        {
                            try
                            {
                                VisionTool.LoadVMSolution(PcbConfig.VisionProjPath);
                                Log = "加载视觉方案成功";
                                vmPorjLoaded = true;
                            }
                            catch (Exception ex)
                            {
                                Log = ex.Message;
                            }
                        });
                    }
                    else
                    {
                        Log = $"视觉方案不存在[{value}]";
                    }
                }
                _visionProjPath = value;
                this.DoNotify();
            }
        }

        private void Loaded(object obj)
        {
            this.SNInputFocusAction?.Invoke();
            //loaded = true;
            Task.Run(() =>
            {
                try
                {
                    var titile = PcbConfigHelper.Load().Title;
                    Application.Current.Dispatcher.Invoke(() =>
                    {
                        var mwin = Application.Current.MainWindow as MetroWindow;
                        mwin.Title = titile;
                    });
                    PcbConfig = PcbConfigHelper.GetTestConfig();

                    DM3058E.Connect();
                    IT6302A.Connect();
                    IOModule.Connect();

                    CameraTool.Open();

                    if (PcbConfig != null)
                    {
                        foreach (var power in PcbConfig.ListPowerConfig)
                        {
                            IT6302A.SetChannelOutput(power.ChannelIndex, power.IsActive);
                            IT6302A.SetVoltage(power.ChannelIndex, power.Voltage);
                            IT6302A.SetCurrent(power.ChannelIndex, power.Current);
                        }
                    }
                }
                catch (Exception ex)
                {
                    Log = ex.Message;
                    Mylog.Error(ex, ex.Message);
                }
            });
        }

        private void Unloaded(object obj)
        {
        }

        private void Reset(object obj)
        {
            try
            {
                DM3058E.Connect();
                IT6302A.Connect();
                IOModule.Connect();
                IOModule.SetDOValue(DODefine.AirReset, 0);
                IOModule.SetDOValue(DODefine.Power, 0);
                IOModule.SetDOValue(DODefine.NG, 0);
                IOModule.SetDOValue(DODefine.OK, 0);
                TestResult = null;
                this.SNInputFocusAction?.Invoke();
            }
            catch (Exception ex)
            {
                Log = ex.Message;
            }
        }

        private string _sn;

        public string SN
        {
            get { return _sn; }
            set
            {
                _sn = value;
                this.DoNotify();
            }
        }

        private MachineStatus _machineStatus;

        public MachineStatus MachineStatus
        {
            get { return _machineStatus; }
            set { _machineStatus = value; }
        }

        private void Start(object obj)
        {
            // 0 系统状态判定
            switch (MachineStatus)
            {
                case MachineStatus.Running:
                    return;

                case MachineStatus.Stop:
                    if (!IOModule.GetDIValue(DIDefine.SafeLight))
                    {
                        Log = "安全光栅感应";
                        return;
                    }
                    MachineStatus = MachineStatus.Running;
                    break;

                case MachineStatus.EmgStop:
                    Log = "设备处于急停状态";
                    //IOModule.SetDOValue(DODefine.NG, 1);
                    return;

                default:
                    return;
            }

            Task.Run(() =>
            {
                TestResult = null;
                if (SN == null | SN == "")
                {
                    Log = ("SN码不能为空");
                    MachineStatus = MachineStatus.Stop;
                    this.SNInputFocusAction?.Invoke();
                    return;
                }
                if (!vmPorjLoaded)
                {
                    Log = "请等待视觉方案加载完成";
                    MachineStatus = MachineStatus.Stop;
                    this.SNInputFocusAction?.Invoke();
                    return;
                }
                Log = "--------------------";
                TestResultData = new TestResultData();
                TestResultData.SN = SN;
                TestResultData.BurnSucc = true;
                Thread.Sleep(50);
                IOModule.SetDOValue(DODefine.NG, 0);
                Thread.Sleep(50);
                IOModule.SetDOValue(DODefine.OK, 0);
                try
                {
                    if (PcbConfig is null)
                    {
                        throw new Exception("测试方案不能为空");
                    }
                    // 1 气缸下压
                    IOModule.SetDOValue(DODefine.AirReset, 1);

                    bool timeOut1 = false;
                    // 等待气缸到位
                    Task.Run(() =>
                    {
                        Thread.Sleep(5000);
                        timeOut1 = true;
                    });
                    while (true)
                    {
                        if (IOModule.GetDIValue(DIDefine.AirWork))
                        {
                            break;
                        }
                        if (timeOut1)
                        {
                            break;
                        }
                        Thread.Sleep(100);
                    }
                    if (timeOut1)
                    {
                        throw new Exception("等待气缸到位超时");
                    }

                    // 切换烧录模式
                    IOModule.SetDOValue(DODefine.LineSwitch, 1);
                    Thread.Sleep(50);
                    // 2 打开电源
                    IOModule.SetDOValue(DODefine.Power, 1);
                    Thread.Sleep(2000);
                    IOModule.LogIOStatus();
                    // 3烧录
                    if (PcbConfig.BurnConfig.SubBurnConfigs != null)
                    {
                        foreach (var item in PcbConfig.BurnConfig.SubBurnConfigs)
                        {
                            if (!item.IsBurn)
                                continue;
                            TestBurnData testResultBurn = new TestBurnData();

                            bool ret = TPS929120.WriteFlash(PcbConfig.BurnConfig.Port, item.BrunFilePath, item.McuAddress, false);
                            if (ret)
                            {
                                Log = $"芯片地址[{item.McuAddress}]烧录校验成功";
                                testResultBurn.BurnResult = true;
                                testResultBurn.McuAddress = item.McuAddress;
                                TestResultData.TestResultBurns.Add(testResultBurn);
                            }
                            else
                            {
                                foreach (var err in TPS929120.listErr)
                                {
                                    Log = err;
                                }
                                Log = $"芯片地址[{item.McuAddress}]烧录校验失败";
                                throw new Exception("测试失败");
                            }
                        }
                    }

                    // 切换测试模式
                    IOModule.SetDOValue(DODefine.Power, 0);
                    Thread.Sleep(500);
                    IOModule.SetDOValue(DODefine.LineSwitch, 0);
                    Thread.Sleep(500);
                    IOModule.SetDOValue(DODefine.Power, 1);
                    Thread.Sleep(2000);
                    IOModule.LogIOStatus();

                    // 4视觉测试
                    bool result = true;
                    PcbCANControl.Connect();
                    if (PcbConfig.ListLedCurrentConfig is not null)
                    {
                        foreach (var item in PcbConfig.ListLedCurrentConfig)
                        {
                            currentProcName = item.ProcName;
                            Type classType = typeof(HomeViewModel);
                            MethodInfo methodInfo = classType.GetMethod(item.TestMethodName);
                            if (methodInfo == null)
                            {
                                throw new Exception($"测试方法未找到[{item.TestMethodName}]");
                            }
                            bool ret = (bool)methodInfo.Invoke(this, new object[] { item });
                            if (!ret)
                            {
                                result = false;
                            }
                        }
                        if (result)
                        {
                            Log = "测试OK";
                            TestResult = true;
                            IOModule.SetDOValue(DODefine.OK, 1);
                        }
                        else
                        {
                            IOModule.SetDOValue(DODefine.NG, 1);
                            Log = "测试NG";
                            TestResult = false;
                        }
                    }

                    PcbCANControl.DisConnect();
                    IOModule.SetDOValue(DODefine.Power, 0);
                    IOModule.SetDOValue(DODefine.AirReset, 0);
                    MachineStatus = MachineStatus.Stop;
                    TestResultData.Note(TestResultData);
                    SN = "";
                    this.SNInputFocusAction?.Invoke();
                }
                catch (Exception ex)
                {
                    MachineStatus = MachineStatus.Stop;
                    PcbCANControl.DisConnect();
                    IOModule.SetDOValue(DODefine.Power, 0);
                    IOModule.SetDOValue(DODefine.AirReset, 0);
                    IOModule.SetDOValue(DODefine.NG, 1);
                    Log = ex.Message;
                    TestResult = false;
                    Log = (ex.Message);
                    SN = "";
                    this.SNInputFocusAction?.Invoke();
                }
            });
        }

        private string currentProcName;
        public CommandBase StartCommand { get; set; }
        public CommandBase ResetCommand { get; set; }
        public CommandBase UnloadedCommand { get; set; }
        public CommandBase LoadedCommand { get; set; }
        public CommandBase SaveImageCommand { get; set; }

        private void VmSolution_OnWorkStatusEvent(ImvsSdkDefine.IMVS_MODULE_WORK_STAUS workStatusInfo)
        {
            try
            {
                Mylog.Info($"procid[{workStatusInfo.nProcessID}],status[{workStatusInfo.nWorkStatus}]");
                if (workStatusInfo.nWorkStatus == 0 && workStatusInfo.nProcessID == currentProcId)//为0表示执行完毕，为1表示正在执行；10000表示流程1
                {
                    //通过流程获取结果
                    //VmProcedure vmProcess1 = (VmProcedure)VmSolution.Instance[currentProcName];
                    //String radiusResult = vmProcess1.ModuResult.GetOutputFloat("out").pFloatVal[0].ToString();
                    vmResult = VisionTool.GetGlobalVar("result");
                    vmProcHaveExec = true;
                    Console.WriteLine("视觉判断耗时" + swGlobal.ElapsedMilliseconds);
                }
            }
            catch (VmException ex)
            {
                Mylog.Error(ex, ex.Message);
                //ShowMessage(ex.Message);
            }
        }

        private string _log;
        private string vmResult;
        private bool vmProcHaveExec;

        public string Log
        {
            get { return _log; }
            set
            {
                Application.Current.Dispatcher.Invoke(new Action(() =>
                {
                    _log = value;
                    this.DoNotify();
                }));
            }
        }
    }
}